package com.ruoyi.wms.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.wms.domain.WmsOwnerOrderNumberRecord;
import com.ruoyi.wms.mapper.WmsOwnerOrderNumberRecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.wms.mapper.WmsOwnerOrderNumberRuleMapper;
import com.ruoyi.wms.domain.WmsOwnerOrderNumberRule;
import com.ruoyi.wms.service.IWmsOwnerOrderNumberRuleService;

/**
 * 货主订单编号规则配置Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class WmsOwnerOrderNumberRuleServiceImpl implements IWmsOwnerOrderNumberRuleService 
{
    @Autowired
    private WmsOwnerOrderNumberRuleMapper wmsOwnerOrderNumberRuleMapper;

    @Autowired
    private WmsOwnerOrderNumberRecordMapper wmsOwnerOrderNumberRecordMapper;

    /**
     * 查询货主订单编号规则配置
     * 
     * @param ruleId 货主订单编号规则配置主键
     * @return 货主订单编号规则配置
     */
    @Override
    public WmsOwnerOrderNumberRule selectWmsOwnerOrderNumberRuleByRuleId(Long ruleId)
    {
        return wmsOwnerOrderNumberRuleMapper.selectWmsOwnerOrderNumberRuleByRuleId(ruleId);
    }

    /**
     * 查询货主订单编号规则配置列表
     * 
     * @param wmsOwnerOrderNumberRule 货主订单编号规则配置
     * @return 货主订单编号规则配置
     */
    @Override
    public List<WmsOwnerOrderNumberRule> selectWmsOwnerOrderNumberRuleList(WmsOwnerOrderNumberRule wmsOwnerOrderNumberRule)
    {
        return wmsOwnerOrderNumberRuleMapper.selectWmsOwnerOrderNumberRuleList(wmsOwnerOrderNumberRule);
    }

    /**
     * 根据货主ID查询规则配置列表
     * 
     * @param ownerId 货主ID
     * @return 货主订单编号规则配置集合
     */
    @Override
    public List<WmsOwnerOrderNumberRule> selectRuleListByOwnerId(Long ownerId)
    {
        WmsOwnerOrderNumberRule rule = new WmsOwnerOrderNumberRule();
        rule.setOwnerId(ownerId);
        return wmsOwnerOrderNumberRuleMapper.selectWmsOwnerOrderNumberRuleList(rule);
    }

    /**
     * 新增货主订单编号规则配置
     * 
     * @param wmsOwnerOrderNumberRule 货主订单编号规则配置
     * @return 结果
     */
    @Override
    public int insertWmsOwnerOrderNumberRule(WmsOwnerOrderNumberRule wmsOwnerOrderNumberRule)
    {
        wmsOwnerOrderNumberRule.setCreateTime(DateUtils.getNowDate());
        wmsOwnerOrderNumberRule.setCreateBy(SecurityUtils.getUsername());
        return wmsOwnerOrderNumberRuleMapper.insertWmsOwnerOrderNumberRule(wmsOwnerOrderNumberRule);
    }

    /**
     * 修改货主订单编号规则配置
     * 
     * @param wmsOwnerOrderNumberRule 货主订单编号规则配置
     * @return 结果
     */
    @Override
    public int updateWmsOwnerOrderNumberRule(WmsOwnerOrderNumberRule wmsOwnerOrderNumberRule)
    {
        wmsOwnerOrderNumberRule.setUpdateTime(DateUtils.getNowDate());
        wmsOwnerOrderNumberRule.setUpdateBy(SecurityUtils.getUsername());
        return wmsOwnerOrderNumberRuleMapper.updateWmsOwnerOrderNumberRule(wmsOwnerOrderNumberRule);
    }

    /**
     * 批量删除货主订单编号规则配置
     * 
     * @param ruleIds 需要删除的货主订单编号规则配置主键
     * @return 结果
     */
    @Override
    public int deleteWmsOwnerOrderNumberRuleByRuleIds(Long[] ruleIds)
    {
        return wmsOwnerOrderNumberRuleMapper.deleteWmsOwnerOrderNumberRuleByRuleIds(ruleIds);
    }

    /**
     * 删除货主订单编号规则配置信息
     * 
     * @param ruleId 货主订单编号规则配置主键
     * @return 结果
     */
    @Override
    public int deleteWmsOwnerOrderNumberRuleByRuleId(Long ruleId)
    {
        return wmsOwnerOrderNumberRuleMapper.deleteWmsOwnerOrderNumberRuleByRuleId(ruleId);
    }

    /**
     * 根据货主ID删除规则配置
     * 
     * @param ownerId 货主ID
     * @return 结果
     */
    @Override
    public int deleteWmsOwnerOrderNumberRuleByOwnerId(Long ownerId)
    {
        return wmsOwnerOrderNumberRuleMapper.deleteWmsOwnerOrderNumberRuleByOwnerId(ownerId);
    }

    /**
     * 生成订单编号
     * 
     * @param ownerId 货主ID
     * @param orderType 订单类型
     * @return 生成的订单编号
     */
    @Override
    @Transactional
    public String generateOrderNumber(Long ownerId, String orderType)
    {
        // 查询规则配置
        WmsOwnerOrderNumberRule rule = wmsOwnerOrderNumberRuleMapper.selectRuleByOwnerIdAndOrderType(ownerId, orderType);
        if (rule == null) {
            throw new RuntimeException("未找到货主订单编号规则配置");
        }

        // 获取当前日期
        Date currentDate = new Date();
        
        // 查询或创建当日记录（加锁防止并发问题）
        WmsOwnerOrderNumberRecord record = wmsOwnerOrderNumberRecordMapper.selectRecordByOwnerIdAndOrderTypeAndDate(ownerId, orderType, currentDate);
        
        Integer nextSerial;
        if (record == null) {
            // 创建新记录，第一次使用起始值
            nextSerial = rule.getSerialStart();
            
            record = new WmsOwnerOrderNumberRecord();
            record.setTenantId(rule.getTenantId());
            record.setOwnerId(ownerId);
            record.setOrderType(orderType);
            record.setRuleId(rule.getRuleId());
            record.setGenerateDate(currentDate);
            record.setCurrentSerial(nextSerial);
            record.setCreateTime(DateUtils.getNowDate());
            record.setUpdateTime(DateUtils.getNowDate());
            
            // 生成订单编号
            String orderNumber = buildOrderNumber(rule, currentDate, nextSerial);
            record.setLastOrderNo(orderNumber);
            
            // 插入记录
            wmsOwnerOrderNumberRecordMapper.insertWmsOwnerOrderNumberRecord(record);
            
            return orderNumber;
        } else {
            // 更新现有记录，流水号递增
            nextSerial = record.getCurrentSerial() + 1;
            
            // 生成订单编号
            String orderNumber = buildOrderNumber(rule, currentDate, nextSerial);
            
            // 更新记录
            wmsOwnerOrderNumberRecordMapper.updateCurrentSerial(record.getRecordId(), nextSerial, orderNumber);
            
            return orderNumber;
        }
    }

    /**
     * 预览订单编号格式
     * 
     * @param wmsOwnerOrderNumberRule 规则配置
     * @return 预览的订单编号
     */
    @Override
    public String previewOrderNumber(WmsOwnerOrderNumberRule wmsOwnerOrderNumberRule)
    {
        Date currentDate = new Date();
        Integer previewSerial = wmsOwnerOrderNumberRule.getSerialStart() != null ? wmsOwnerOrderNumberRule.getSerialStart() : 1;
        return buildOrderNumber(wmsOwnerOrderNumberRule, currentDate, previewSerial);
    }

    /**
     * 构建订单编号
     * 
     * @param rule 规则配置
     * @param date 日期
     * @param serial 流水号
     * @return 订单编号
     */
    private String buildOrderNumber(WmsOwnerOrderNumberRule rule, Date date, Integer serial)
    {
        StringBuilder orderNumber = new StringBuilder();
        
        // 添加前缀
        if (rule.getPrefix() != null && !rule.getPrefix().isEmpty()) {
            orderNumber.append(rule.getPrefix());
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                orderNumber.append(rule.getDivision());
            }
        }
        
        // 添加日期
        if (rule.getDateFormat() != null && !rule.getDateFormat().isEmpty()) {
            SimpleDateFormat sdf = new SimpleDateFormat(rule.getDateFormat());
            orderNumber.append(sdf.format(date));
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                orderNumber.append(rule.getDivision());
            }
        }
        
        // 添加流水号
        String serialStr = String.format("%0" + rule.getSerialLength() + "d", serial);
        orderNumber.append(serialStr);
        
        // 添加后缀
        if (rule.getSuffix() != null && !rule.getSuffix().isEmpty()) {
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                orderNumber.append(rule.getDivision());
            }
            orderNumber.append(rule.getSuffix());
        }
        
        return orderNumber.toString();
    }
    
    /**
     * 验证订单编号格式
     * 
     * @param ownerId 货主ID
     * @param orderType 订单类型
     * @param orderNumber 待验证的订单编号
     * @return 验证结果
     */
    @Override
    public boolean validateOrderNumber(Long ownerId, String orderType, String orderNumber)
    {
        try {
            // 查询规则配置
            WmsOwnerOrderNumberRule rule = wmsOwnerOrderNumberRuleMapper.selectRuleByOwnerIdAndOrderType(ownerId, orderType);
            if (rule == null) {
                return false;
            }
            
            // 验证订单编号格式
            return validateOrderNumberFormat(rule, orderNumber);
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 验证订单编号格式是否符合规则
     * 
     * @param rule 规则配置
     * @param orderNumber 待验证的订单编号
     * @return 验证结果
     */
    private boolean validateOrderNumberFormat(WmsOwnerOrderNumberRule rule, String orderNumber)
    {
        if (orderNumber == null || orderNumber.isEmpty()) {
            return false;
        }
        
        int currentIndex = 0;
        
        // 验证前缀
        if (rule.getPrefix() != null && !rule.getPrefix().isEmpty()) {
            if (!orderNumber.startsWith(rule.getPrefix())) {
                return false;
            }
            currentIndex += rule.getPrefix().length();
            
            // 验证分隔符
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                if (currentIndex >= orderNumber.length() || 
                    !orderNumber.substring(currentIndex).startsWith(rule.getDivision())) {
                    return false;
                }
                currentIndex += rule.getDivision().length();
            }
        }
        
        // 验证日期格式
        if (rule.getDateFormat() != null && !rule.getDateFormat().isEmpty()) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(rule.getDateFormat());
                int dateLength = rule.getDateFormat().length();
                
                if (currentIndex + dateLength > orderNumber.length()) {
                    return false;
                }
                
                String dateStr = orderNumber.substring(currentIndex, currentIndex + dateLength);
                sdf.parse(dateStr); // 验证日期格式是否正确
                currentIndex += dateLength;
                
                // 验证分隔符
                if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                    if (currentIndex >= orderNumber.length() || 
                        !orderNumber.substring(currentIndex).startsWith(rule.getDivision())) {
                        return false;
                    }
                    currentIndex += rule.getDivision().length();
                }
            } catch (Exception e) {
                return false;
            }
        }
        
        // 验证流水号长度
        int serialLength = rule.getSerialLength() != null ? rule.getSerialLength() : 4;
        int remainingLength = orderNumber.length() - currentIndex;
        
        // 如果有后缀，需要减去后缀和分隔符的长度
        if (rule.getSuffix() != null && !rule.getSuffix().isEmpty()) {
            remainingLength -= rule.getSuffix().length();
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                remainingLength -= rule.getDivision().length();
            }
        }
        
        if (remainingLength != serialLength) {
            return false;
        }
        
        // 验证流水号是否为数字
        String serialStr = orderNumber.substring(currentIndex, currentIndex + serialLength);
        try {
            Integer.parseInt(serialStr);
        } catch (NumberFormatException e) {
            return false;
        }
        
        currentIndex += serialLength;
        
        // 验证后缀
        if (rule.getSuffix() != null && !rule.getSuffix().isEmpty()) {
            // 验证分隔符
            if (rule.getDivision() != null && !rule.getDivision().isEmpty()) {
                if (currentIndex >= orderNumber.length() || 
                    !orderNumber.substring(currentIndex).startsWith(rule.getDivision())) {
                    return false;
                }
                currentIndex += rule.getDivision().length();
            }
            
            if (!orderNumber.substring(currentIndex).equals(rule.getSuffix())) {
                return false;
            }
        }
        
        return true;
    }
}